package com.xiangxg.jvm.classloader;

import java.sql.Driver;
import java.util.Iterator;
import java.util.ServiceLoader;

/*
    线程上下文类加载器的一般使用模式（获取 - 使用 - 还原）
    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(classloader);
            myMethod();
        } finally {
            Thread.currentThread().setContextClassLoader(classloader);
        }
     myMethod();里面则调用 了  Thread.currentThread().getContextClassLoader();
     获取当前线程的上下文加载器做某些事情。

     如果一个类由类加载器A加载，那么这个类的依赖类也是由相同的类加载器加载的（如果
     该依赖类之前没有被加载过）

     ContextClassLoader的作用就是为了破坏java的类加载委托机制
     在SPI的接口中实现线程上线文加载器就可以加载到SPI实现类
     当高层提供了统一的接口让低层区实现，同时又要在高层加载（或实例化）低层类时，就必需要
     通过线程上下文类加载器来帮助高层classloader找到并加载该类


 */
public class MyTest26 {
    public static void main(String[] args) {
        //测试场景：修改线程上下文类加载器
        //Thread.currentThread().setContextClassLoader(MyTest26.class.getClassLoader().getParent());

        ServiceLoader loader = ServiceLoader.load(Driver.class);
        Iterator<Driver> iterator = loader.iterator();
        while (iterator.hasNext()){
            Driver driver = iterator.next();
            System.out.println("driver: " + driver.getClass()+", loader: " + driver.getClass().getClassLoader());
        }
        System.out.println("当前线程上下文类加载器："+ Thread.currentThread().getContextClassLoader());
        System.out.println("ServiceLoader的类加载器： "+ServiceLoader.class.getClassLoader());


    }
}
